using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text;
using ZoneFiveSoftware.Common.Visuals;
using System.Globalization;

namespace STCommon.View
{
    public class ExtendedTreeList : TreeList
    {
        public ExtendedTreeList()
        {
            RowDataRenderer = new ExtendedRowDataRenderer(this);
        }

        public object RowHitTest(Point position, RowHitState state)
        {
            state = RowHitState.Row;
            return RowHitTest(position);
        }

        public object RowHitTest(Point position)
        {
            int rowNumber;
            bool isInUpperHalf;

            return RowHitTest(position, out rowNumber, out isInUpperHalf);
        }

        public object RowHitTest(Point position, out int rowNumber, out bool isInUpperHalf)
        {
            IList rows = ((ExtendedRowDataRenderer)RowDataRenderer).GetRows();
            int rowY = position.Y;
            int i = VScrollBar.Value - 1;
            object currentRowElement = null;

            do
            {
                i++;
                currentRowElement = rows[i];
                rowY -= RowDataRenderer.RowHeight(currentRowElement);
            }
            while (rowY > 0 && i < rows.Count - 1);

            // This is past the last row
            if (rowY > 0)
            {
                currentRowElement = null;
                rowNumber = -1;
                isInUpperHalf = false;
            }
            else
            {
                rowNumber = i;
                isInUpperHalf = -rowY > RowDataRenderer.RowHeight(currentRowElement) / 2.0f;
            }

            return currentRowElement;
        }

        public new IRowDataRenderer RowDataRenderer
        {
            get
            {
                Debug.Assert(typeof(ExtendedRowDataRenderer).IsInstanceOfType(base.RowDataRenderer));

                return base.RowDataRenderer;
            }
            set
            {
                Debug.Assert(typeof(ExtendedRowDataRenderer).IsInstanceOfType(value));

                base.RowDataRenderer = value;
            }
        }

        public new void SetSortIndicator(String columnId, bool isAscending)
        {
            base.SetSortIndicator(columnId, isAscending);

            m_SortedColumnId = columnId;
            m_SortAscending = isAscending;
        }

        public void GetSortIndicator(out String columnId, out bool isAscending)
        {
            columnId = m_SortedColumnId;
            isAscending = m_SortAscending;
        }

        public void ExportToCSV(Stream exportStream)
        {
            IList rows = ((ExtendedRowDataRenderer)RowDataRenderer).GetRows();

            foreach (TreeList.Column column in this.Columns)
            {
                ExportCellToCSV(column.Text,
                                column == this.Columns[this.Columns.Count - 1],
                                exportStream);
            }
            ExportEndlineToCSV(exportStream);

            foreach (object row in rows)
            {
                foreach (TreeList.Column column in this.Columns)
                {
                    ExportCellToCSV(this.LabelProvider.GetText(row, column),
                                    column == this.Columns[this.Columns.Count - 1],
                                    exportStream);
                }
                ExportEndlineToCSV(exportStream);
            }
        }

        private void ExportCellToCSV(String cellText, bool bLastRowCell, Stream exportStream)
        {
            Double value;
            String exportValue;

            if (Double.TryParse(cellText, out value))
            {
                // Export as number, make sure to format decimals with a "." (invariant culture)
                exportValue = value.ToString(CultureInfo.InvariantCulture.NumberFormat);
            }
            else
            {
                // Export as string
                exportValue = cellText;

                if (exportValue.Contains("\n") ||
                    exportValue.Contains("\r") ||
                    exportValue.Contains("\"") ||
                    exportValue.Contains(",") ||
                    String.IsNullOrEmpty(cellText))
                {
                    // Replace quotes with double quotes
                    exportValue = exportValue.Replace("\"", "\"\"");

                    // Enclose in quotes
                    exportValue = "\"" + exportValue + "\"";
                }
            }

            if (!bLastRowCell)
            {
                exportValue = exportValue + ",";
            }

            // Save in stream
            exportStream.Write(Encoding.UTF8.GetBytes(exportValue), 0, exportValue.Length);
        }

        private void ExportEndlineToCSV(Stream exportStream)
        {
            exportStream.WriteByte(13);     // CR
            exportStream.WriteByte(10);     // LF
        }

        private String m_SortedColumnId = String.Empty;
        private bool m_SortAscending = true;
    }
}
